/*
 * Copyright (c) 2014 Steve Tracey
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package com.stevetracey.backup;

import org.apache.commons.io.monitor.FileAlterationListener;
import org.apache.commons.io.monitor.FileAlterationMonitor;
import org.apache.commons.io.monitor.FileAlterationObserver;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.stevetracey.backup.io.google.GoogleDrive;
import com.stevetracey.common.Configuration;

import java.io.File;
import java.io.IOException;



public class FileChangeWatcher implements FileAlterationListener
{

	private static Log log = LogFactory.getLog(FileChangeWatcher.class);

	private static final int POLL_INTERVAL = Configuration
			.getIntValue("file.watcher.poll.interval.minutes");

	private FileAlterationMonitor monitor;

	private BackupJobContext BACKUP_CONF;


	public FileChangeWatcher(BackupJobContext pBackupConfig)
	{
		{
			this.BACKUP_CONF = pBackupConfig;
		}

		try
		{
			File directory = new File(pBackupConfig.getLocalSourceFolderPath());
			log.info("Creating new file watcher with interval " + POLL_INTERVAL + " mins for "
					+ directory.getAbsolutePath());

			FileAlterationObserver observer = new FileAlterationObserver(directory);
			observer.addListener(this);

			this.monitor = new FileAlterationMonitor(POLL_INTERVAL * 1000 * 60);

			monitor.addObserver(observer);


		}
		catch (Exception e)
		{
			e.printStackTrace();
			log.error("Failed to intialise watcher for " + pBackupConfig.getLocalSourceFolderPath());
		}

	}

	public void start() {
		try
		{
			monitor.start();
		}
		catch (Exception e)
		{
			e.printStackTrace();
			log.error("Failed to start monitor", e);
		}
	}

	public void stop() {
		try
		{
			log.info("Filewatcher stopping...");
			monitor.stop();
		}
		catch (Exception e)
		{
			e.printStackTrace();
			log.error("Failed to stop monitor", e);
		}
	}

	@Override
	public void onDirectoryChange(File pFile) {
		log.debug("Change detected to " + pFile.getAbsolutePath());

	}

	@Override
	public void onDirectoryCreate(File pFile) {
		log.debug("Change detected to " + pFile.getAbsolutePath());

	}

	@Override
	public void onDirectoryDelete(File pFile) {
		log.debug("Change detected to " + pFile.getAbsolutePath());

	}

	@Override
	public void onFileChange(File pFile) {
		log.info("Change detected to " + pFile.getAbsolutePath());
		try
		{
			GoogleDrive.syncFile(pFile, BACKUP_CONF);
		}
		catch (IOException e)
		{
			log.error("Failure syncing folders",e);
		}
	}

	@Override
	public void onFileCreate(File pFile) {
		log.info("New file detected " + pFile.getAbsolutePath());
		try
		{
			GoogleDrive.syncFile(pFile, BACKUP_CONF);
		}
		catch (IOException e)
		{
			log.error("Failure syncing folders",e);
		}
	}

	@Override
	public void onFileDelete(File pFile) {
		log.info("File deletion detected, no action taken: " + pFile.getAbsolutePath());
	}

	@Override
	public void onStart(FileAlterationObserver pObserver) {
		log.trace("Starting observer for [" + BACKUP_CONF.getLocalSourceFolderPath() + "]");

	}

	@Override
	public void onStop(FileAlterationObserver pObserver) {
		log.trace("Stopping observer for [" + BACKUP_CONF.getLocalSourceFolderPath() + "]");

	}
}
